﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace AutoParkingManagement
{
    public partial class MainParent : Form
    {
        #region Private members
        private static bool _isLogon = false;
        private static Working _empWorking = null;
        private string _userName = String.Empty;
        private string _password = String.Empty;
        private string IpServer = String.Empty;       

        /// <summary>
        /// Get current employee information
        /// </summary>
        private void GetEmployeeInfo()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT EmployeeID, [Code], FirstName, LastName, PermissionID ");
            sb.Append("FROM Employee ");
            sb.Append("WHERE UserName=@UserName");
            string strCommandText = sb.ToString();
            SqlParameter parm = new SqlParameter("@UserName", SqlDbType.NVarChar, 50);
            parm.Value = _userName;

            SqlDataReader objReader = SqlHelper.ExecuteReader(CommandType.Text, strCommandText, parm);

            if (objReader == null) return;

            if (objReader.Read())
            {
                _empWorking.Employee.Id = objReader.GetGuid(0);
                _empWorking.Employee.Code = objReader.GetString(1);
                _empWorking.Employee.FirstName = objReader.GetString(2);
                _empWorking.Employee.LastName = objReader.GetString(3);
                _empWorking.Employee.Permission = new Permission();
                _empWorking.Employee.Permission.Id = objReader.GetString(4);
            }
        }

        /// <summary>
        /// Update last login
        /// </summary>
        private void UpdateLastLogin()
        {
            if (_empWorking.Employee.Id == Guid.Empty) return;
            StringBuilder sb = new StringBuilder();
            sb.Append("UPDATE Employee ");
            sb.Append("SET LastLogin=GetDate() ");
            sb.Append("WHERE EmployeeID=@EmployeeID");
            SqlParameter parm = new SqlParameter("@EmployeeID", SqlDbType.UniqueIdentifier);
            parm.Value = _empWorking.Employee.Id;
            SqlHelper.ExecuteNonQuery(CommandType.Text, sb.ToString(), parm);
            _empWorking.Employee.Id = Guid.Empty;
        }

        /// <summary>
        /// Get shift information by current time
        /// </summary>
        private void GetShiftInfo()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT ShiftID, [Name], ");
            sb.Append("FromTime, ");
            sb.Append("ToTime, ");
            sb.Append("GetDate() AS CurrentTime ");
            sb.Append("FROM Shift");
            string strCommandText = sb.ToString();

            SqlDataReader objReader = SqlHelper.ExecuteReader(CommandType.Text, strCommandText, null);

            if (objReader == null) return;

            while (objReader.Read())
            {
                int fromTime = int.Parse(objReader.GetDateTime(2).ToString("HHmmss"));
                int toTime = int.Parse(objReader.GetDateTime(3).ToString("HHmmss"));
                if (fromTime > toTime) toTime += 240000;
                int currentTime = int.Parse(objReader.GetDateTime(4).ToString("HHmmss"));
                if (currentTime >= fromTime && currentTime < toTime)
                {
                    _empWorking.Shift = new Shift();
                    _empWorking.Shift.Id = objReader.GetByte(0);
                    _empWorking.Shift.Name = objReader.GetString(1);
                }
            }
        }

        private bool NotLogOut(Guid empId)
        {
            string sql = @"SELECT TOP 1 WorkingId, [LogoutTime]      
                          FROM [Working]  
                          WHERE EmployeeID=@EmployeeID
                          ORDER BY LastUpdate DESC";
            SqlParameter parm = new SqlParameter("EmployeeId", SqlDbType.UniqueIdentifier);
            parm.Value = empId;
            SqlDataReader objReader = SqlHelper.ExecuteReader(CommandType.Text, sql, parm);
            if (objReader.Read())
            {
                _empWorking.Id = objReader.GetGuid(0);
                return String.IsNullOrEmpty(objReader[1].ToString());
            }
            return false;
        }

        /// <summary>
        /// Insert new working information
        /// </summary>
        /// <returns>true: insert, false: cancel</returns>
        private bool InsertWorking()
        {
            if (_empWorking.Employee.Permission.Id != "01" || NotLogOut(_empWorking.Employee.Id)) return true;
            _empWorking.Id = Guid.NewGuid();
            GetShiftInfo();
            StringBuilder sb = new StringBuilder();
            sb.Append("INSERT INTO Working (WorkingID, EmployeeID, ShiftID, ShiftName, LastUser) ");
            sb.Append("VALUES (@WorkingID, @EmployeeID, @ShiftID, @ShiftName, @LastUser)");

            SqlParameter[] parms = new SqlParameter[5];
            parms[0] = new SqlParameter("@WorkingID", SqlDbType.UniqueIdentifier);
            parms[0].Value = _empWorking.Id;

            parms[1] = new SqlParameter("@EmployeeID", SqlDbType.UniqueIdentifier);
            parms[1].Value = _empWorking.Employee.Id;

            parms[2] = new SqlParameter("@ShiftID", SqlDbType.TinyInt);
            parms[3] = new SqlParameter("@ShiftName", SqlDbType.NVarChar, 50);
            if (_empWorking.Shift == null)
            {
                parms[2].Value = DBNull.Value;
                parms[3].Value = DBNull.Value;
            }
            else
            {
                parms[2].Value = _empWorking.Shift.Id;
                parms[3].Value = _empWorking.Shift.Name;
            }


            parms[4] = new SqlParameter("@LastUser", SqlDbType.UniqueIdentifier);
            parms[4].Value = _empWorking.Employee.Id;

            SqlHelper.ExecuteNonQuery(CommandType.Text, sb.ToString(), parms);

            return true;
        }

        private void UpdateWorking()
        {
            if (_empWorking.Employee.Permission.Id != "01") return;
            if (_empWorking.Employee.Id == Guid.Empty) return;
            StringBuilder sb = new StringBuilder();
            sb.Append("UPDATE Working ");
            sb.Append("SET LogoutTime = GetDate(), LastUpdate = GetDate() ");
            sb.Append("WHERE WorkingID=@WorkingID");
            SqlParameter parm = new SqlParameter("@WorkingID", SqlDbType.UniqueIdentifier);
            parm.Value = _empWorking.Id;
            SqlHelper.ExecuteNonQuery(CommandType.Text, sb.ToString(), parm);
            _empWorking.Id = Guid.Empty;
        }

        /// <summary>
        /// Run after login/logout
        /// </summary>
        /// <param name="status">true: login, false: logout</param>
        private void SetLoginText(bool status)
        {
            _isLogon = status;            
            if (status)
            {
                this.Activate();                
                _userName = Login.Username;
                _password = Login.Password;
                //Get employee informaton by username
                GetEmployeeInfo();                
                ///////////////////////////////////////
                mnuLogin.Text = "Đăng xuất";
                mnuChangePassword.Visible = status;
                switch (Login.Permission)
                {
                    case Common.SYSTEM_PERMISSIONS.VEHICLE_KEEPER:
                        mnuManageCar.Visible = status;
                        mnuEntryExit_Click(null, null);
                        break;
                    case Common.SYSTEM_PERMISSIONS.ACCOUNTANT:                        
                        mnuManageCar.Visible = status;
                        mnuManageCard.Visible = status;
                        mnuCardList_Click(null, null);
                        break;
                    case Common.SYSTEM_PERMISSIONS.MANAGER:
                        mnuManageCar.Visible = status;
                        mnuManageCard.Visible = status;
                        mnuCardList_Click(null, null);
                        break;
                    default:
                        mnuManageCar.Visible = status;
                        mnuManageCard.Visible = status;
                        mnuCardList_Click(null, null);
                        break;
                }
            }
            else
            {                
                Login.Username = String.Empty;
                Login.Password = String.Empty;
                mnuSystem.Text = "Đăng nhập";
                //Close all form in MDI form
                foreach (Form childForm in MdiChildren)
                {
                    childForm.Close();
                }
                mnuLogin_Click(null, null);
            }
        }

        /// <summary>
        /// Run after password changed
        /// </summary>
        /// <param name="isChanged">true: changed; false: not change</param>
        private void frmChangePassword_PasswordChanged(bool isChanged)
        {
            if (isChanged)
            {
                mnuLogin_Click(null, null);
            }
        }

        private void frm_EntryExitClosed()
        {
            UpdateWorking();
            this.Show();
            this.Activate();
        }

        private void frm_VehicleSearched()
        {
            mnuSearchCar_Click(null, null);
        }
        
        #endregion

        #region Properties
        public static Working EmpWorking
        {
            get
            {
                return _empWorking;
            }
            set
            {
                _empWorking = value;
            }
        }

        public static bool IsLogon
        {
            get
            {
                return _isLogon;
            }
            set
            {
                _isLogon = value;
            }
        }

        #endregion

        #region Public members
        
        #endregion

        #region Events

        private void SetTimer()
        {
            IpServer = AppConfig.IpServer;
            if (AppConfig.RefreshTime > 0)
            {
                timerSyncTime.Interval = AppConfig.RefreshTime * 1000;
                timerSyncTime.Enabled = true;
                timerSyncTime.Start();
            }
            else
            {
                timerSyncTime.Enabled = false;
            }
        }

        private void MainParent_Load(object sender, EventArgs e)
        {
            try
            {
                SetTimer();                
                _empWorking = new Working();
                _empWorking.Id = Guid.Empty;
                _empWorking.Employee = new Employee();
                _empWorking.Employee.Id = Guid.Empty;
                SetLoginText(false);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Lỗi hệ thống.\nVui lòng liên hệ quản trị hệ thống để được hỗ trợ.");
            }
        }        

                
        private void mnuLogin_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            Login frmLogin;
            if (!_isLogon)
            {
                frmLogin = new Login();
                frmLogin.LoginChanged += new Login.LoginChangedHandler(SetLoginText);
                frmLogin.StartPosition = FormStartPosition.CenterScreen;
                frmLogin.ShowDialog();
            }
            else
            {
                SetLoginText(false);
                UpdateLastLogin();
            }
            this.Activate();
            Cursor.Current = Cursors.Default;
        }

        private void mnuChangePassword_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            ChangePassword frmChangePassword;
            frmChangePassword = new ChangePassword(_userName, _password);
            frmChangePassword.PasswordChanged += new ChangePassword.PasswordChangedHandler(frmChangePassword_PasswordChanged);
            frmChangePassword.StartPosition = FormStartPosition.CenterScreen;
            frmChangePassword.ShowDialog();
            this.Activate();
            Cursor.Current = Cursors.Default;
        }

        private void mnuExit_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Bạn muốn đóng chương trình?", this.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Environment.Exit(Environment.ExitCode);
            }            
        }

        private void mnuEntryExit_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                InsertWorking();
                this.Hide();
                if (!Common.FormExisted(typeof(EntryExitContainer)))
                {
                    string strFullName = String.Format("{0} {1} ({2})", _empWorking.Employee.FirstName,
                                                            _empWorking.Employee.LastName,
                                                            _empWorking.Employee.Code).Trim();
                    EntryExitContainer frm = new EntryExitContainer(_userName, strFullName);
                    frm.EntryExitClosed += new EntryExitContainer.EntryExitClosedHandler(frm_EntryExitClosed);
                    frm.VehicleSearched += new EntryExitContainer.SearchVehicleHandler(frm_VehicleSearched);
                    frm.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }            
        }       
        

        private void mnuSearchCar_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            if (!Common.FormExisted(typeof(SearchCar)))
            {
                Form frm = new SearchCar();
                frm.MdiParent = this;
                frm.WindowState = FormWindowState.Maximized;
                frm.ControlBox = false;
                frm.Show();
            }
            Cursor.Current = Cursors.Default;
        }
        

        private void mnuCardList_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;


            if (!Common.FormExisted(typeof(CardList)))
            {
                Form frm = new CardList();
                frm.MdiParent = this;
                frm.WindowState = FormWindowState.Maximized;
                frm.ControlBox = false;
                frm.Show();
            }
            Cursor.Current = Cursors.Default;
        }

        private void mnuOrderList_Click(object sender, EventArgs e)
        {
            //Cursor.Current = Cursors.WaitCursor;
            //if (!Common.FormExisted(typeof(OrderList)))
            //{
            //    Form frm = new OrderList();
            //    frm.MdiParent = this;
            //    frm.WindowState = FormWindowState.Maximized;
            //    frm.ControlBox = false;
            //    frm.Show();
            //}
            //Cursor.Current = Cursors.Default;
        }

        private void mnuSaleCard_Click(object sender, EventArgs e)
        {
            //Cursor.Current = Cursors.WaitCursor;
            //if (!Common.FormExisted(typeof(UpdateOrderDetails)))
            //{
            //    Form frm = new UpdateOrderDetails();
            //    frm.MdiParent = this;
            //    frm.WindowState = FormWindowState.Maximized;
            //    frm.ControlBox = false;
            //    frm.Show();
            //}
            //Cursor.Current = Cursors.Default;
        }

        private void mnuCustomer_Click(object sender, EventArgs e)
        {
            //Cursor.Current = Cursors.WaitCursor;
            //if (!Common.FormExisted(typeof(CustomerList)))
            //{
            //    Form frm = new CustomerList();
            //    frm.MdiParent = this;
            //    frm.WindowState = FormWindowState.Maximized;
            //    frm.ControlBox = false;
            //    frm.Show();
            //}
            //Cursor.Current = Cursors.Default;
        }

        private void timerSyncTime_Tick(object sender, EventArgs e)
        {
            try
            {                
                this.Invoke((MethodInvoker)delegate
                {
                    Common.ExecuteCommandSync(IpServer);
                });
            }
            catch
            {
                System.Threading.Thread.Sleep(3000);
            }
        }

        private void MainParent_FormClosed(object sender, FormClosedEventArgs e)
        {
            UpdateLastLogin();
        }
        
        #endregion

        #region Constructors
        public MainParent()
        {
            InitializeComponent();
        }        

        #endregion
       
    }
}
